package cc.iotkit.openapi.controller;

import cc.iotkit.common.api.Paging;
import cc.iotkit.common.api.Request;
import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DevicePropertyCache;
import cc.iotkit.temporal.IThingModelMessageData;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = {"openapi-能耗分析"})
@Slf4j
@RestController
@RequestMapping("/openapi/electricity")
public class ElectricityOpenApi {
    @Autowired
    @Qualifier("deviceInfoDataCache")
    private IDeviceInfoData deviceInfoData;
    @Autowired
    private IDeviceManagerService deviceServiceImpl;
    @Autowired
    private IThingModelMessageData thingModelMessageData;

    @ApiOperation("1、获取位置列表")
    @GetMapping("/v1/getClasses")
    @SaCheckLogin
    public JSONArray runStatistics() {
        JSONArray jsonArray = new JSONArray();
        JSONObject object = new JSONObject();
        object.put("id","0");
        object.put("no",0);
        object.put("title","整栋");
        jsonArray.add(object);

        object = new JSONObject();
        object.put("id","1");
        object.put("no",1);
        object.put("title","一层");
        jsonArray.add(object);

        object = new JSONObject();
        object.put("id","2");
        object.put("no",2);
        object.put("title","二层");
        jsonArray.add(object);

        return jsonArray;
    }

    @ApiOperation("2、当前负荷")
    @PostMapping("/v1/getElectricEnergy")
    @SaCheckLogin
    public JSONObject getElectricEnergy(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        Float power = 0f;
        List<String> ids = null;
        List<DeviceInfo> deviceInfoList = deviceInfoData.findByPk(Constants.ELECTRICAL_MI_PK);
        Float accumulateDay = 0f;
        Float electricEnergy = 0f;
        Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
        Date startDate = DateUtils.addDays(endDate, -1);
        for (DeviceInfo deviceInfo:deviceInfoList) {
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());

            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            float d1 = 0;
            float d2 = 0;
            float p1 = 0;
            float p2 = 0;
            if (messageList.size()>0) {
                Map<String, Object> o1 = (Map<String, Object>) messageList.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) messageList.get(messageList.size() - 1).getData();
                if (o1 != null && o1.get("electricEnergy") != null) {
                    d1 = Float.parseFloat(o1.get("electricEnergy") + "");
                }
                if (o2 != null && o2.get("electricEnergy") != null) {
                    d2 = Float.parseFloat(o2.get("electricEnergy") + "");
                }
                if (o1 != null && o1.get("power") != null) {
                    p1 = Float.parseFloat(o1.get("power") + "");
                }
                if (o2 != null && o2.get("power") != null) {
                    p2 = Float.parseFloat(o2.get("power") + "");
                }
            }
            electricEnergy+=(d2-d1);
            accumulateDay+=(p2);
        }
        JSONObject object = new JSONObject();

        object.put("currentLoad",String.format("%.2f", accumulateDay));
        return object;
    }

    @ApiOperation("3、获取当日负荷峰值及峰值时间")
    @PostMapping("/v1/peakElectricityData")
    @SaCheckLogin
    public JSONObject peakElectricityData(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
        Date startDate = DateUtils.addDays(endDate, -1);
        //按楼层找出设备ID集合
        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData() != null && objectRequest.getData().get("flag") != null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);

        float peakLoad = 0;
        int peakTime = 0;
        List<String> devIds;
        for (DeviceInfo deviceInfo:deviceInfoList) {
            devIds = new ArrayList<>();
            devIds.add(deviceInfo.getDeviceId());
            List<ThingModelMessage> thingModelMessageList = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            thingModelMessageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            // 将记录按小时聚合分组
            Map<LocalDateTime, List<ThingModelMessage>> groupedByHour = thingModelMessageList.stream()
                    .collect(Collectors.groupingBy(
                            x -> (new Date(x.getTime())).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withMinute(0).withSecond(0).withNano(0) // 将时间设置为整点
                    ));

            //分组聚合所有用电量
            for (Map.Entry<LocalDateTime, List<ThingModelMessage>> entry : groupedByHour.entrySet()) {
                LocalDateTime key = entry.getKey();
                List<ThingModelMessage> value = entry.getValue();
                //聚合计算当前小时下的能耗
                Map<String, Object> o1 = (Map<String, Object>) value.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) value.get(value.size() - 1).getData();
                float f1 = o1.get("electricEnergy") == null ? 0 : Float.parseFloat(o1.get("electricEnergy") + "");
                float f2 = o2.get("electricEnergy") == null ? 0 : Float.parseFloat(o2.get("electricEnergy") + "");
                if (peakLoad == 0 || peakLoad < (f2 - f1)) {
                    peakLoad = f2 - f1;
                    peakTime = key.getHour();
                }
            }
        }
        JSONObject object = new JSONObject();
        object.put("peakLoad",String.format("%.2f", peakLoad));
        object.put("peakTime",peakTime);
        return object;
    }

    @ApiOperation("4、获取当日累计用电情况")
    @PostMapping("/v1/todayElectricityData")
    @SaCheckLogin
    public JSONObject todayElectricityData(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);
        Float electricEnergy = 0f;

        List<String> ids = null;
        for (DeviceInfo deviceInfo:deviceInfoList) {
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());
            Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
            Date startDate = DateUtils.addDays(endDate, -1);

            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            float d1 = 0;
            float d2 = 0;
            if (messageList.size()>0) {
                Map<String, Object> o1 = (Map<String, Object>) messageList.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) messageList.get(messageList.size() - 1).getData();
                if (o1 != null && o1.get("electricEnergy") != null) {
                    d1 = Float.parseFloat(o1.get("electricEnergy") + "");
                }
                if (o2 != null && o2.get("electricEnergy") != null) {
                    d2 = Float.parseFloat(o2.get("electricEnergy") + "");
                }
            }
            electricEnergy+=(d2-d1);
        }

        JSONObject object = new JSONObject();
        object.put("grandTotal",String.format("%.2f", electricEnergy));
        return object;
    }

    @ApiOperation("5、分区域统计")
    @PostMapping("/v1/todayRoomElectricityData")
    @SaCheckLogin
    public JSONArray todayRoomElectricityData(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }

        JSONArray jsonArray = new JSONArray();
        JSONObject object;

        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);
        List<String> ids = null;
        Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
        Date startDate = DateUtils.addDays(endDate, -1);
        for (DeviceInfo deviceInfo:deviceInfoList) {
            Float electricEnergy = 0f;
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());

            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            float d1 = 0;
            float d2 = 0;
            if (messageList.size()>0) {
                Map<String, Object> o1 = (Map<String, Object>) messageList.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) messageList.get(messageList.size() - 1).getData();
                if (o1 != null && o1.get("electricEnergy") != null) {
                    d1 = Float.parseFloat(o1.get("electricEnergy") + "");
                }
                if (o2 != null && o2.get("electricEnergy") != null) {
                    d2 = Float.parseFloat(o2.get("electricEnergy") + "");
                }
            }
            electricEnergy+=(d2-d1);
//            electricEnergy+=(d2);
            object = new JSONObject();
            object.put("name", deviceInfo.getDeviceName());
            object.put("value", String.format("%.2f", electricEnergy));
            jsonArray.add(object);
        }
        return jsonArray;
    }

    @ApiOperation("6、获取当日用电排名")
    @PostMapping("/v1/todayElectricityDataSort")
    @SaCheckLogin
    public JSONArray todayElectricityDataSort(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }

        JSONArray jsonArray = new JSONArray();
        JSONObject object;

        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);
        List<String> ids = null;
        for (DeviceInfo deviceInfo:deviceInfoList) {
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());
            Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
            Date startDate = DateUtils.addDays(endDate, -1);

            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            float d1 = 0;
            float d2 = 0;
            if (messageList.size()>0) {
                Map<String, Object> o1 = (Map<String, Object>) messageList.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) messageList.get(messageList.size() - 1).getData();
                if (o1 != null && o1.get("electricEnergy") != null) {
                    d1 = Float.parseFloat(o1.get("electricEnergy") + "");
                }
                if (o2 != null && o2.get("electricEnergy") != null) {
                    d2 = Float.parseFloat(o2.get("electricEnergy") + "");
                }
            }
            object = new JSONObject();
            object.put("name", deviceInfo.getDeviceName());
            object.put("current", String.format("%.2f", d2-d1));
            jsonArray.add(object);
        }

        List<JSONObject> list = JSONArray.parseArray(jsonArray.toJSONString(), JSONObject.class);
        Collections.sort(list, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                float a = o1.getFloat("current");
                float b = o2.getFloat("current");
                if (a > b) {
                    return -1;
                } else if(a == b) {
                    return 0;
                } else
                    return 1;
            }
        });
        if (list!=null && list.size()>0) {
            jsonArray = JSONArray.parseArray(list.toString());
        }
        return jsonArray;
    }

    @ApiOperation("7、日用用电曲线")
    @PostMapping("/v1/powerDay")
    @SaCheckLogin
    public JSONObject powerDay(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        JSONObject returnJSON = new JSONObject();
        float today = 0;
        float yesterday = 0;

        JSONObject charts = new JSONObject();

        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);

        //查询今日用电
        Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
        Date startDate = DateUtils.addDays(endDate, -1);

        Date endDate1 = DateUtils.addDays(startDate, -1);
        Date startDate1 = DateUtils.addDays(endDate1, -1);

        //填充近24小时数据
        int[] xAxisData24 = new int[24];
        int h=0;
        for (int i=startDate.getHours();i<24;i++){
            xAxisData24[h] = i;
            h++;
        }
        for (int i=1;i<endDate.getHours();i++){
            xAxisData24[h] = i;
            h++;
        }
        charts.put("xAxisData",xAxisData24);

//==============================================================================近24小时===============================
        float[] all = new float[24];
        //根据设备ID获取设备的上报日志==
        List<String> devIds= new ArrayList<>();
        for (DeviceInfo deviceInfo:deviceInfoList) {
            devIds = new ArrayList<>();
            devIds.add(deviceInfo.getDeviceId());
            List<ThingModelMessage> thingModelMessageList = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            thingModelMessageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            // 将记录按小时聚合分组
            Map<LocalDateTime, List<ThingModelMessage>> groupedByHour = thingModelMessageList.stream()
                    .collect(Collectors.groupingBy(
                            x -> (new Date(x.getTime())).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withMinute(0).withSecond(0).withNano(0) // 将时间设置为整点
                    ));

            //分组聚合所有用电量
            for (Map.Entry<LocalDateTime, List<ThingModelMessage>> entry : groupedByHour.entrySet()) {
                LocalDateTime key = entry.getKey();
                List<ThingModelMessage> value = entry.getValue();

                for (int i = 0; i < 24; i++) {
                    if (xAxisData24[i] == key.getHour()) {
                        //聚合计算当前小时下的能耗
                        float a = 0f;
                        Map<String, Object> o1 = (Map<String, Object>) value.get(value.size()-1).getData();
                        Map<String, Object> o2 = (Map<String, Object>) value.get(0).getData();
                        if (o2 != null && o2.get("electricEnergy") != null && o1!=null && o1.get("electricEnergy") != null) {
                            a = Float.parseFloat(o2.get("electricEnergy")+"") - Float.parseFloat(o1.get("electricEnergy")+"");
                            if (a<0){
                                a = Float.parseFloat(o1.get("electricEnergy")+"") - Float.parseFloat(o2.get("electricEnergy")+"");
                            }
                        }

                        all[i] += a;
                        today += a;
                        break;
                    }
                }
            }
            charts.put("seriesData1", all);
        }

        //根据设备ID获取设备的上报日志====================================前天
        for (DeviceInfo deviceInfo:deviceInfoList) {
            devIds = new ArrayList<>();
            devIds.add(deviceInfo.getDeviceId());
            List<ThingModelMessage> thingModelMessageList = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY, null, startDate1.getTime(), endDate1.getTime());
            thingModelMessageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            // 将记录按小时聚合分组
            Map<LocalDateTime, List<ThingModelMessage>> groupedByHour = thingModelMessageList.stream()
                    .collect(Collectors.groupingBy(
                            x -> (new Date(x.getTime())).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withMinute(0).withSecond(0).withNano(0) // 将时间设置为整点
                    ));

            //分组聚合所有用电量
            float[] all2 = new float[24];
            for (Map.Entry<LocalDateTime, List<ThingModelMessage>> entry : groupedByHour.entrySet()) {
                LocalDateTime key = entry.getKey();
                List<ThingModelMessage> value = entry.getValue();
                for (int i = 0; i < 24; i++) {
                    if (xAxisData24[i] == key.getHour()) {
                        //聚合计算当前小时下的能耗
                        float a = 0f;
                        Map<String, Object> o1 = (Map<String, Object>) value.get(value.size()-1).getData();
                        Map<String, Object> o2 = (Map<String, Object>) value.get(0).getData();
                        if (o2 != null && o2.get("electricEnergy") != null && o1!=null && o1.get("electricEnergy") != null) {
                            a = Float.parseFloat(o2.get("electricEnergy")+"") - Float.parseFloat(o1.get("electricEnergy")+"");
                            if (a<0){
                                a = Float.parseFloat(o1.get("electricEnergy")+"") - Float.parseFloat(o2.get("electricEnergy")+"");
                            }
                        }
                        all2[i] += a;
                        yesterday += a;
                        break;
                    }
                }
            }
            charts.put("seriesData2", all2);
        }
        returnJSON.put("charts",charts);
        float ratio=0f;
        String status = "持平";
        if (yesterday>0) {
            if (today > yesterday) {
                ratio = (today - yesterday) / yesterday * 100;
                status = "上升";
            } else if (today < yesterday) {
                ratio = (yesterday - today) / yesterday * 100;
                status = "下降";
            } else if (yesterday == 0 && today > 0) {
                ratio = 100;
            }
        }else {
            ratio = 100;
            status = "上升";
        }

        returnJSON.put("ratio",String.format("%.2f", ratio));
        returnJSON.put("status",status);
        return returnJSON;
    }

    @ApiOperation("8、近30天的用电情况")
    @PostMapping("/v1/powerMonth")
    @SaCheckLogin
    public JSONObject powerMonth(@RequestBody @Validated Request<JSONObject> objectRequest) {
        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        float all1 = 0f;
        float all2 = 0f;
        // 获取当前日期
        Calendar calendar = new GregorianCalendar();
        Date currentDate = new Date();
        calendar.setTime(currentDate);
        // 减去29天--加上当天共30天
        calendar.add(Calendar.DAY_OF_MONTH, -29);
        // 获取30天前的日期
        Date date30DaysAgo = calendar.getTime();
        //按楼层找出设备ID集合
        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData() != null && objectRequest.getData().get("flag") != null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);
        List<String> devIds = new ArrayList<>();
        for (DeviceInfo deviceInfo : deviceInfoList) {
            devIds.add(deviceInfo.getDeviceId());
        }
        //将当前楼层所有 的产品的用电集合
        List<ThingModelMessage> thingModelMessageList = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY, null,  date30DaysAgo.getTime(), currentDate.getTime());
        thingModelMessageList.sort(new Comparator<ThingModelMessage>() {
            @Override
            public int compare(ThingModelMessage o1, ThingModelMessage o2) {
                int r = o1.getTime().compareTo(o2.getTime());
                if (r == 0) {
                    return o1.getId().compareTo(o2.getId());
                }
                return r;
            }
        });
        JSONObject charts = new JSONObject();
        Instant instant = date30DaysAgo.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate startDate = instant.atZone(zoneId).toLocalDate();

        Instant instant1 = currentDate.toInstant();
        ZoneId zoneId1 = ZoneId.systemDefault();
        LocalDate endDate = instant1.atZone(zoneId1).toLocalDate();
        // 获取两个日期之间的所有日期
        List<LocalDate> datesBetween = cc.iotkit.common.utils.DateUtils.datesBetween(startDate,endDate);
        int[] xAxisData = new int[datesBetween.size()];

        for (int i=0;i<datesBetween.size();i++){
            xAxisData[i] = datesBetween.get(i).getDayOfMonth();
        }
        JSONObject jsonObject = new JSONObject();

        List<String> ids = null;
        float[] electricityData = new float[datesBetween.size()];

        for (DeviceInfo deviceInfo:deviceInfoList) {
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());

            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, date30DaysAgo.getTime(), currentDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            // 将记录按天聚合分组
            Map<LocalDateTime, List<ThingModelMessage>> groupedByDay = messageList.stream()
                    .collect(Collectors.groupingBy(
                            y -> (new Date(y.getTime())).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withHour(0).withMinute(0).withSecond(0).withNano(0) // 将时间设置为整点
                    ));
            for (int i=0;i<datesBetween.size();i++){
                for (LocalDateTime localDateTime:groupedByDay.keySet()){
                    if (datesBetween.get(i).getDayOfMonth()==localDateTime.getDayOfMonth() && datesBetween.get(i).getMonth()==localDateTime.getMonth()){
                        List<ThingModelMessage> modelMessageList = groupedByDay.get(localDateTime);
                        float a = 0f;
                        Map<String, Object> o1 = (Map<String, Object>) modelMessageList.get(modelMessageList.size()-1).getData();
                        Map<String, Object> o2 = (Map<String, Object>) modelMessageList.get(0).getData();
                        if (o2 != null && o2.get("electricEnergy") != null && o1!=null && o1.get("electricEnergy") != null) {
                            a = Float.parseFloat(o2.get("electricEnergy")+"") - Float.parseFloat(o1.get("electricEnergy")+"");
                            if (a<0){
                                a = Float.parseFloat(o1.get("electricEnergy")+"") - Float.parseFloat(o2.get("electricEnergy")+"");
                            }
                        }
                        electricityData[i] += a;
                        all1+=a;
                        break;
                    }
                }
            }
        }

        charts.put("xAxisData",xAxisData);
        charts.put("electricityData",electricityData);
        jsonObject.put("charts",charts);

// 获取当前日期
        // 减去29天--加上当天共30天
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        // 获取30天前的日期
        Date date30DaysAgo1 = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, -29);
        Date date60DaysAgo2 = calendar.getTime();

        //将当前楼层所有 的产品的用电集合
//        thingModelMessageList = thingModelMessageData.findByTypeAndDeviceIdsAll(devIds, ThingModelMessage.TYPE_PROPERTY, null, date60DaysAgo2.getTime(), date30DaysAgo1.getTime());
//        for (ThingModelMessage thingModelMessage:thingModelMessageList){
//            if (thingModelMessage.getData()!=null && ((LinkedHashMap)thingModelMessage.getData()).get("electricEnergy")!=null) {
//                all2 = Float.parseFloat(((LinkedHashMap) thingModelMessage.getData()).get("electricEnergy").toString());
//            }
//        }
        float ratio=0f;
        String status = "持平";
        if(all2==0 && all1>0){
            ratio = 100;
            status = "上升";
        }else {
            if (all1 > all2) {
                ratio = (all1 - all2) / all2 * 100;
                status = "上升";
            } else if (all1 < all2) {
                status = "下降";
                ratio = (all2 - all1) / all2 * 100;
            }
        }
        jsonObject.put("ratio",String.format("%.2f", ratio));
        jsonObject.put("status",status);
        return jsonObject;
    }
    @ApiOperation("9、近30天的用电分项统计")
    @PostMapping("/v1/powerSubMonth")
    @SaCheckLogin
    public JSONArray powerSubMonth(@RequestBody @Validated Request<JSONObject> objectRequest) {

        if (objectRequest.getData()!=null && objectRequest.getData().get("flag")!=null && "整栋".equals(objectRequest.getData().get("flag"))) {
            objectRequest.getData().put("flag",null);
        }
        // 获取当前日期
        Calendar calendar = new GregorianCalendar();
        Date currentDate = new Date();
        calendar.setTime(currentDate);
        // 减去29天--加上当天共30天
        calendar.add(Calendar.DAY_OF_MONTH, -29);
        // 获取30天前的日期
        Date startDate = calendar.getTime();
        Date endDate = DateUtils.ceiling(new Date(), Calendar.HOUR);
        //按楼层找出设备ID集合
        DeviceInfo condition = new DeviceInfo();
        condition.setProductKey(Constants.ELECTRICAL_MI_PK);
        if (objectRequest.getData() != null && objectRequest.getData().get("flag") != null) {
            condition.setFloor(objectRequest.getData().getString("flag"));
        }
        condition.setState(null);
        List<DeviceInfo> deviceInfoList = deviceInfoData.findAllByCondition(condition);
        List<String> devIds = new ArrayList<>();
        for (DeviceInfo deviceInfo : deviceInfoList) {
            devIds.add(deviceInfo.getDeviceId());
        }
        JSONObject object;
        JSONArray jsonArray = new JSONArray();
        List<String> ids = null;
        //循环设备封装用电量
        for (DeviceInfo deviceInfo:deviceInfoList) {
            object = new JSONObject();
            ids = new ArrayList<>();
            ids.add(deviceInfo.getDeviceId());
            List<ThingModelMessage> messageList = thingModelMessageData.findByTypeAndDeviceIdsAll(ids, ThingModelMessage.TYPE_PROPERTY, null, startDate.getTime(), endDate.getTime());
            messageList.sort(new Comparator<ThingModelMessage>() {
                @Override
                public int compare(ThingModelMessage o1, ThingModelMessage o2) {

                    int r = o1.getTime().compareTo(o2.getTime());
                    if (r == 0) {
                        return o1.getId().compareTo(o2.getId());
                    }
                    return r;

                }
            });
            float d1 = 0;
            float d2 = 0;
            if (messageList.size()>0) {
                Map<String, Object> o1 = (Map<String, Object>) messageList.get(0).getData();
                Map<String, Object> o2 = (Map<String, Object>) messageList.get(messageList.size() - 1).getData();
                if (o1 != null && o1.get("electricEnergy") != null) {
                    d1 = Float.parseFloat(o1.get("electricEnergy") + "");
                }
                if (o2 != null && o2.get("electricEnergy") != null) {
                    d2 = Float.parseFloat(o2.get("electricEnergy") + "");
                }
            }
            object.put("name", deviceInfo.getDeviceName());
            object.put("value", String.format("%.2f", (d2-d1)));
            jsonArray.add(object);
        }
        return jsonArray;
    }
}
